package com.nkym.wypan.storage.core;/*
 * @ClassName AbstractStorageEngine
 * @Desc TODO
 * @Author 19637
 * @Date 2023/6/11 11:51
 * @Version 1.0
 */

import com.nkym.wypan.storage.context.*;

import java.util.List;

import java.io.OutputStream;

import cn.hutool.core.lang.Assert;

import com.nkym.wypan.storage.response.UploadResult;

import java.io.IOException;
import java.io.InputStream;

public abstract class AbstractStorageEngine implements StorageEngine {
    @Override
    public UploadResult upload(FileUpload fileUpload) throws IOException {
        //校验参数
        checkParameters(fileUpload);
        //文件上传
        UploadResult result = doStore(fileUpload);
        return result;
    }

    @Override
    public void preview(PreviewRequest previewRequest) {
        checkPreViewParameter(previewRequest);
        doPreview(previewRequest);
    }

    @Override
    public void download(String realPath, OutputStream outputStream, Long startPosition, Long size) {
        Assert.notBlank(realPath, "文件路径不能为空");
        Assert.notNull(outputStream, "文件流不能为空");
        Assert.notNull(startPosition, "文件读入位置不能为空");
        Assert.notNull(size, "文件大小不能为空");
        doDownload(realPath,outputStream,startPosition,size);
    }




    @Override
    public void download(Download download) {
        checkDownloadParameters(download);
        try {
            doDownload(download);
        } catch (Exception e) {
            throw new RuntimeException("文件异常");
        }
    }

    @Override
    public UploadResult mergeChunk(MergeRequest chunkRequest) throws IOException {
        checkMergeChunkParameters(chunkRequest);
        UploadResult r = doMerge(chunkRequest);
        return r;
    }

    @Override
    public void delete(DeleteRequest deleteRequest) {
        checkDeleteParameters(deleteRequest);
        doDelete(deleteRequest);
    }


    @Override
    public UploadResult chunkUpload(ChunkUpload chunkUpload) throws IOException {
        checkChunkUploadParameters(chunkUpload);
        UploadResult result = doChunkUpload(chunkUpload);
        return result;
    }

    /**
     * -----------------------------------------abstract method----------------------------------------------------
     */
    protected abstract void doDownload(String realPath, OutputStream outputStream, Long startPosition, Long size);
    protected abstract void doPreview(PreviewRequest previewRequest);


    protected abstract void doDelete(DeleteRequest deleteRequest);

    protected abstract UploadResult doMerge(MergeRequest chunkRequest) throws IOException;

    protected abstract void doDownload(Download download) throws IOException;

    protected abstract UploadResult doStore(FileUpload fileUpload) throws IOException;

    protected abstract UploadResult doChunkUpload(ChunkUpload chunkUpload) throws IOException;

    /**
     * ------------------------------private--------------------------------------------------------
     */

    private void checkPreViewParameter(PreviewRequest previewRequest) {
        String realPath = previewRequest.getRealPath();
        OutputStream stream = previewRequest.getStream();
        Assert.notBlank(realPath, "路径不能为空");
        Assert.notNull(stream, "文件流不能为空");

    }

    private void checkDeleteParameters(DeleteRequest deleteRequest) {
        String realPath = deleteRequest.getRealPath();
        Assert.notBlank(realPath, "删除路径不能为空");
    }

    private void checkMergeChunkParameters(MergeRequest chunkRequest) {
        List<Merge> mergeList = chunkRequest.getMergeList();
        Assert.notEmpty(mergeList, "合并列表不能为空");

    }

    private void checkChunkUploadParameters(ChunkUpload chunkUpload) {
        Integer chunkNumber = chunkUpload.getChunkNumber();
        String identifier = chunkUpload.getIdentifier();
        InputStream inputStream = chunkUpload.getInputStream();
        Long chunkFileSize = chunkUpload.getChunkFileSize();
        Assert.notNull(chunkNumber, "分片编号不能为空");
        Assert.notNull(identifier, "文件标识不能为空");
        Assert.notNull(inputStream, "文件流不能为空");
        Assert.notNull(chunkFileSize, "分片大小不能为空");
    }


    /**
     * ----------------------------------------------------------------------------------------
     */
    private void checkParameters(FileUpload fileUpload) {
        String filename = fileUpload.getFilename();
        InputStream stream = fileUpload.getStream();
        Assert.notNull(stream, "上传文件不能为空");
        Assert.notBlank(filename, "文件名不能为空");
    }

    private void checkDownloadParameters(Download download) {
        String realPath = download.getRealPath();
        OutputStream outputStream = download.getOutputStream();
        Assert.notNull(outputStream, "响应流不能未空");
        Assert.notBlank(realPath, "请求路径不能为空");
    }


}
